package com.codingday.app;


import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import com.codingday.app.MyLocation.LocationResult;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;
import com.google.android.maps.Overlay;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.location.Address;
import android.location.Criteria;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Looper;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import android.widget.Toast;

public class MapLocPicker extends MapActivity {

	MapView googleMap;
	MapController mc;
	/*
	Criteria cta;
	LocationManager locationManager;
	String provider;
	*/
	
	Address address;
	double latitude;
	double longitude;
	int radius;
	
	EditText et_Search;
	Button bt_myLocation;
	Button bt_selectLocationDone;
	SeekBar seekbar;
	
	List<Overlay> mapOverlays; 
	Drawable drawable;
	
	boolean editMode = false;
	
	MyLocation myLocation = null;
	LocationResult locationResult = null;
	MapLocPicker instance = null;
	//MapsItemizedOverlay itemizedOverlay;

	@Override
	protected void onCreate(Bundle icicle) {
		// TODO Auto-generated method stub
		super.onCreate(icicle);
		instance = this;
		//InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
		
		
		setContentView(R.layout.map_loc_picker);
		googleMap = (MapView) findViewById(R.id.maps);
		mc = googleMap.getController();
		et_Search = (EditText) findViewById(R.id.edit_text_search);
		//imm.hideSoftInputFromWindow(edtiTextSearch.getWindowToken(), 0);
		//locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);

		//checkProvider();
		initMapView();
		InitButtons();
		
		GeoPoint p = null;
		Intent intent = getIntent();
		editMode = intent.getBooleanExtra("EditMode", false);
		
		if(editMode == true){
			double latitude = intent.getDoubleExtra("LATITUDE", 0);
			double longitude = intent.getDoubleExtra("LONGITUDE", 0);
			int radius = intent.getIntExtra("RADIUS", 0);
			p = new GeoPoint((int)(latitude*1E6), (int)(longitude*1E6));
			this.latitude = latitude;
			this.longitude = longitude;
			this.radius = radius;
		}else{
			Location location = GeoAlarm.getInstance().getService().getLastKnownLocation();
			if(location != null){
				p = new GeoPoint(((int)(location.getLatitude()*1E6)), ((int)(location.getLongitude()*1E6)));
				this.latitude = location.getLatitude();
				this.longitude = location.getLongitude(); 

			}else{
				p = new GeoPoint(0,0);
			}
			mc.setZoom(16);			
		}
		mc.animateTo(p);

		
		mapOverlays = googleMap.getOverlays(); 
	}

	
	@Override
	protected void onResume() {
		super.onResume();
		Log.i("TODOMapView","Resume---------------------------------");
		initMapView();
		//googleMap.invalidate();
		//initMapView();
		//myLocation.getLocation(this, locationResult, 10000);
		//ProgressDialog progressDialog = new ProgressDialog(this);
		if(editMode == false){
			final ProgressDialog pd = ProgressDialog.show(this, "", this.getString(R.string.map_waiting_msg));
	
			myLocation = new MyLocation();
			locationResult = new LocationResult(){
	
				@Override
				public void gotLocation(Location location) {
					// TODO Auto-generated method stub
					pd.dismiss();
					Log.i("TODOMapView","gotLocation");
					initMapPosition(location);
				}
				
			};
			myLocation.getLocation(this, locationResult, 10000);
		}else{
			mapOverlays.add(new OverlayCircle());
		}

	}

	@Override
	protected void onPause() {
		// TODO Auto-generated method stub
		super.onPause();
		myLocation = null;
	}


	
	public void updateSomeLocation(double latitude, double longitude){
		this.latitude = latitude;
		this.longitude = longitude;
		
		GeoPoint p = new GeoPoint( (int)(latitude*1E6), (int)(longitude*1E6));
		mc = googleMap.getController();
		mc.animateTo(p);
	}

	
	public void initMapView(){
		googleMap.setStreetView(true);
		googleMap.setBuiltInZoomControls(true);
		//mc = googleMap.getController();
		/*
		Location location = GeoAlarm.getInstance().getService().getLastKnownLocation();
		if(location != null){
			GeoPoint p = new GeoPoint(((int)(location.getLatitude()*1E6)), ((int)(location.getLongitude()*1E6)));
			mc.animateTo(p);
		}
		mc.setZoom(17);
		*/		
	}

	public void initMapPosition(Location location){

		
		try {
			Looper.prepare();
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
		Log.i("initMapPosition","Found your Location!");
		if(location == null){
			Log.i("TODOMapView","initMapPosition : location is null");
		}
		GeoPoint p = new GeoPoint(((int)(location.getLatitude()*1E6)), ((int)(location.getLongitude()*1E6)));
		mapOverlays.clear();
		this.latitude = location.getLatitude();
		this.longitude = location.getLongitude();
		mapOverlays.add(new OverlayCircle());
		mapOverlays.add(new OverlayYou(this,location.getLatitude(),location.getLongitude()));
		mc.animateTo(p);
		mc.setZoom(16);
	}
	
	
	@Override
	protected boolean isRouteDisplayed() {
		// TODO Auto-generated method stub
		return false;
	}
	
	public void InitButtons(){

		et_Search.setOnEditorActionListener(new OnEditorActionListener(){

			@Override
			public boolean onEditorAction(TextView v, int actionId,	KeyEvent event) {
				
				if(event == null){
					return false;
				}
				
				if(event.getAction() != KeyEvent.ACTION_DOWN){
					return false;
				}

				// get GPS Info by address
				String searchText = v.getText().toString();
				//Toast.makeText(getApplicationContext(), searchText, 1).show();
				

				Geocoder gc = new Geocoder(getApplicationContext(),Locale.getDefault());
				try {
					List<Address> address = gc.getFromLocationName(searchText, 50);
					if(address != null){
						if(address.size() == 1){
							String result = address.get(0).toString();
							Log.i("Address","result : " + result);
							latitude = address.get(0).getLatitude();
							longitude = address.get(0).getLongitude();

							//Toast.makeText(getApplicationContext(), "Address : "+latitude+","+longitude, 1).show();
							GeoPoint p = new GeoPoint((int)(latitude*1000000),(int)(longitude*1000000));
							mc.animateTo(p);
						}else if(address.size() > 1){
							//Toast.makeText(getApplicationContext(), ""+address.size(), 1).show();
							//
							selectLocationDialog(address);
						}else{
							Toast.makeText(getApplicationContext(), "No Matching Place", 1).show();
						}
					}
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
				InputMethodManager imm = (InputMethodManager) getSystemService( Context.INPUT_METHOD_SERVICE);
				imm.hideSoftInputFromWindow(v.getApplicationWindowToken(), 0); 
				return true;
			}
			
		});
		
		bt_myLocation = (Button) findViewById(R.id.button_my_location);
		bt_myLocation.setOnClickListener(new OnClickListener(){

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub

				//Location location = locationManager.getLastKnownLocation(provider);
				//updateWithNewLoc(location);
				//updateMyLocation();
				//GeoPoint p = new GeoPoint((int)(latitude*1E6), (int)(longitude * 1E6));
				final ProgressDialog pd = ProgressDialog.show(v.getContext(), "", "Where are you?");
				
				myLocation = new MyLocation();
				locationResult = new LocationResult(){

					@Override
					public void gotLocation(Location location) {
						// TODO Auto-generated method stub
						pd.dismiss();
						Log.i("MapLocPicker","gotLocation");
						//int zoom = mc.
						initMapPosition(location);
					}
					
				};
				myLocation.getLocation(instance, locationResult, 7000);
				//mc.animateTo(p);
				
			}
			
		});
		
		bt_selectLocationDone = (Button) findViewById(R.id.map_position_select);
		bt_selectLocationDone.setOnClickListener(new OnClickListener(){

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				goBack();
			}
			
		});
		
		radius = 100;
		seekbar = (SeekBar) findViewById(R.id.slide_radius);
		seekbar.setMax(1000);
		seekbar.setProgress(radius);
		seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener(){

			@Override
			public void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) {
				// TODO Auto-generated method stub
				Log.i("MapLocPicker","SeekBar Change 1 args : " + arg1 +"," + arg2);
				if(arg1 < 50){
					radius = 50;
				}else{
					radius = arg1;
				}
				googleMap.invalidate();
			}

			@Override
			public void onStartTrackingTouch(SeekBar arg0) {
				// TODO Auto-generated method stub
				Log.i("MapLocPicker","SeekBar Change 2");
			}

			@Override
			public void onStopTrackingTouch(SeekBar arg0) {
				// TODO Auto-generated method stub
				Log.i("MapLocPicker","SeekBar Change 3");
			}
			
		});
		
	}
	
	
	public void selectLocationDialog(final List<Address> address){
		AlertDialog.Builder ab = new AlertDialog.Builder(this);
		ab.setTitle("Total "+address.size()+" places");
		final CharSequence[] locations = new CharSequence[address.size()];
		for(int i = 0 ; i < address.size() ; i++){
			StringBuffer fullAddress = new StringBuffer();

			for(int j = 0 ; j < address.get(i).getMaxAddressLineIndex() ; j++){
				fullAddress.append(address.get(i).getAddressLine(j));
				if(j< address.get(i).getMaxAddressLineIndex()-1){
					fullAddress.append(",");
				}
			}
			locations[i] = fullAddress.toString();
		}
		
		ab.setSingleChoiceItems(locations, 0,
				new DialogInterface.OnClickListener() {
					
					@Override
					public void onClick(DialogInterface dialog, int which) {
						// TODO Auto-generated method stub
						//Toast.makeText(getApplicationContext(), locations[which], 1).show();
						final double latitude = address.get(which).getLatitude();
						final double longitude = address.get(which).getLongitude();
						Log.i("Address",address.get(which).toString());
						updateSomeLocation(latitude, longitude);
						dialog.cancel();
						
					}
				});
		AlertDialog alert = ab.create();
		alert.show();
	}
	
	
	@Override
	public void onBackPressed() {
		// TODO Auto-generated method stub
		//super.onBackPressed();
		goBack();
	}

	public void goBack(){
		//Toast.makeText(getApplicationContext(), "Done", 1).show();
		Intent result = new Intent();
		result.putExtra("location_latitude", latitude);
		result.putExtra("location_longitude", longitude);
		result.putExtra("location_radius", radius);
		setResult(Activity.RESULT_OK, result);				
		finish();
	}


	private class OverlayCircle extends Overlay{

		@Override
		public boolean onTap(GeoPoint p, MapView arg1) {
			// TODO Auto-generated method stub
			
			//Toast.makeText(getApplicationContext(), ""+p.getLatitudeE6()+","+p.getLongitudeE6(), 1).show();
			final double latitude = ((double)p.getLatitudeE6())/1E6;
			final double longitude = ((double)p.getLongitudeE6())/1E6;
			updateSomeLocation(latitude, longitude);
			return super.onTap(p, arg1);
		}

		@Override
		public void draw(Canvas canvas, MapView mapView, boolean shadow) {
			// TODO Auto-generated method stub
			super.draw(canvas, mapView, shadow);
			 Paint paint1 = new Paint();
		     //Paint paint2 = new Paint();

		     paint1.setARGB(56, 200, 0, 255); // a, r, g, b
		     //paint2.setARGB(255, 255, 0,0);

		    
		     GeoPoint geoPoint = new GeoPoint((int)(latitude*1E6), (int)(longitude*1E6)); 
		     Point pixPoint = new Point(); 
		     mapView.getProjection().toPixels(geoPoint, pixPoint); 
		     
		     int radiusR = metersToRadius(radius, mapView, latitude);
		     canvas.drawCircle(pixPoint.x, pixPoint.y, radiusR, paint1);
		    
		}
	}

		private static int metersToRadius(float meters, MapView map, double latitude) {
		    return (int) (map.getProjection().metersToEquatorPixels(meters) * (1/ Math.cos(Math.toRadians(latitude))));         
		}


}
